package com.thread.test20180827.lock;


import org.junit.Test;

/**
 * @Description: 执行测试方法
 * lock()方法，用来获取锁。如果锁已被其他线程获取，则进行等待。
 * <p>
 * 与synchronized相比，lock可以知道线程是否获得了锁。
 * 1.lock不是java内置关键字，是juc下的一个接口，通过这个接口的ReentrantLock类可以实现同步访问
 * 2.synchronized是在jvm层面实现的，通过monitor监视器实现。在出现异常时，jvm会自动释放。
 * lock则不行使用Lock必须在try{}catch{}块中进行，并且将释放锁的操作放在finally块中进行，以保证锁一定被被释放，防止死锁的发生。
 * 3.在资源竞争不是特别激烈的情况下，synchronized性能优于lock，而在特别激烈的情况下，lock的性能则优于synchronized
 * <p>
 * 可重入锁的原理是在锁内部维护了一个线程标示，标示该锁目前被那个线程占用，然后关联一个计数器，一开始计数器值为0，说明该锁没有被任何线程占用，
 * 当一个线程获取了该锁，计数器会变成1，其他线程在获取该锁时候发现锁的所有者不是自己所以被阻塞，
 * 但是当获取该锁的线程再次获取锁时候发现锁拥有者是自己会把计数器值+1， 当释放锁后计数器会-1，当计数器为0时候，锁里面的线程标示重置为null,这时
 * 候阻塞的线程会获取被唤醒来获取该锁.
 * --ReentrantLock 类实现了Lock ，它拥有与synchronized 相同的并发性和内存语义，但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。
 * 此外，它还提供了在激烈争用情况下更佳的性能。（换句话说，当许多线程都想访问共享资源时，JVM 可以花更少的时候来调度线程，把更多时间
 * 用在执行线程上。）
 * @author: conceit
 * @Date: 2018/8/27 14:17
 */
public class MainTest {


    public static void main(String[] args) throws InterruptedException {
        //new MainTest().lock();
        new MainTest().unLock();
    }

    /**
     * @Description: lock 以锁定的方法
     * @author: conceit
     * @Date: 2018/8/27 23:03
     */
    public void lock() throws InterruptedException {
        LockTest lockTest = new LockTest();
        Thread thread1 = new Thread(lockTest, "西安站");
        Thread thread2 = new Thread(lockTest, "宝鸡站");
        Thread thread3 = new Thread(lockTest, "咸阳站");

        thread1.start();
        thread2.start();
        thread3.start();

    }

    /**
     * @Description: unLock 未加锁的方法
     * @author: conceit
     * @Date: 2018/8/27 23:04
     */
    @Test
    public void unLock() {
        UnLockTest unLockTest = new UnLockTest();
        Thread thread1 = new Thread(unLockTest, "西安站");
        Thread thread2 = new Thread(unLockTest, "宝鸡站");
        Thread thread3 = new Thread(unLockTest, "咸阳站");

        thread1.start();
        thread2.start();
        thread3.start();

    }
}
